Move all theming stack to use GtkStateFlags.
authorCarlos Garnacho <carlosg@gnome.org>
Mon, 16 Aug 2010 17:09:34 +0000 (19:09 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Sat, 4 Dec 2010 14:37:37 +0000 (15:37 +0100)
This support goes from the theming engines, which are able to retrieve
style for different combined states to the CSS provider, where several
state pseudo-classes may be specified, such as:

GtkButton:active:prelight {}

gtk/gtkcssprovider.c
gtk/gtkstylecontext.c
gtk/gtkstylecontext.h
gtk/gtkstyleset.c
gtk/gtkstyleset.h
gtk/gtkthemingengine.c
gtk/gtkthemingengine.h

index 85dcdbbcfea93a7016d91fc7ad750cb7ae7ea357..0ca90fb0b51bca55e5f8f0eb3afb84a1092c0cc7 100644 (file)
@@ -72,7 +72,7 @@ struct SelectorElement
 struct SelectorPath
 {
   GSList *elements;
-  GtkStateType state;
+  GtkStateFlags state;
   guint ref_count;
 };
 
@@ -149,7 +149,6 @@ selector_path_new (void)
   SelectorPath *path;
 
   path = g_slice_new0 (SelectorPath);
-  path->state = GTK_STATE_NORMAL;
   path->ref_count = 1;
 
   return path;
@@ -541,7 +540,7 @@ struct StylePriorityInfo
 {
   guint64 score;
   GHashTable *style;
-  GtkStateType state;
+  GtkStateFlags state;
 };
 
 static GArray *
@@ -654,10 +653,7 @@ gtk_css_provider_get_style (GtkStyleProvider *provider,
               !gtk_style_set_lookup_property (prop, NULL, NULL))
             continue;
 
-          if (info->state == GTK_STATE_NORMAL)
-            gtk_style_set_set_default (set, key, value);
-          else
-            gtk_style_set_set_property (set, key, info->state, value);
+          gtk_style_set_set_property (set, key, info->state, value);
         }
     }
 
@@ -880,14 +876,12 @@ css_provider_commit (GtkCssProvider *css_provider)
 }
 
 static GTokenType
-parse_pseudo_class (GtkCssProvider *css_provider,
-                    GScanner       *scanner,
-                    SelectorPath   *selector,
-                    GtkRegionFlags *flags)
+parse_nth_child (GtkCssProvider *css_provider,
+                 GScanner       *scanner,
+                 GtkRegionFlags *flags)
 {
   ParserSymbol symbol;
 
-  css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
   g_scanner_get_next_token (scanner);
 
   if (scanner->token != G_TOKEN_SYMBOL)
@@ -941,13 +935,51 @@ parse_pseudo_class (GtkCssProvider *css_provider,
     *flags = GTK_REGION_LAST;
   else
     {
-      GtkStateType state;
+      *flags = 0;
+      return G_TOKEN_SYMBOL;
+    }
+
+  return G_TOKEN_NONE;
+}
+
+static GTokenType
+parse_pseudo_class (GtkCssProvider *css_provider,
+                    GScanner       *scanner,
+                    SelectorPath   *selector)
+{
+  GtkStateType state;
 
-      state = GPOINTER_TO_INT (scanner->value.v_symbol);
-      selector->state = state;
+  g_scanner_get_next_token (scanner);
+
+  if (scanner->token != G_TOKEN_SYMBOL)
+    return G_TOKEN_SYMBOL;
+
+  state = GPOINTER_TO_INT (scanner->value.v_symbol);
+
+  switch (state)
+    {
+    case GTK_STATE_ACTIVE:
+      selector->state |= GTK_STATE_FLAG_ACTIVE;
+      break;
+    case GTK_STATE_PRELIGHT:
+      selector->state |= GTK_STATE_FLAG_PRELIGHT;
+      break;
+    case GTK_STATE_SELECTED:
+      selector->state |= GTK_STATE_FLAG_SELECTED;
+      break;
+    case GTK_STATE_INSENSITIVE:
+      selector->state |= GTK_STATE_FLAG_INSENSITIVE;
+      break;
+    case GTK_STATE_INCONSISTENT:
+      selector->state |= GTK_STATE_FLAG_INCONSISTENT;
+      break;
+    case GTK_STATE_FOCUSED:
+      selector->state |= GTK_STATE_FLAG_FOCUSED;
+      break;
+    default:
+      return G_TOKEN_SYMBOL;
     }
 
-  css_provider_pop_scope (css_provider);
   return G_TOKEN_NONE;
 }
 
@@ -1030,18 +1062,39 @@ parse_selector (GtkCssProvider  *css_provider,
 
           region_name = g_strdup (scanner->value.v_identifier);
 
-          /* Parse nth-child type pseudo-class, and
-           * possibly a state pseudo-class after it.
-           */
-          while (path->state == GTK_STATE_NORMAL &&
-                 g_scanner_peek_next_token (scanner) == ':')
+          if (g_scanner_peek_next_token (scanner) == ':')
             {
-              GTokenType token;
+              ParserSymbol symbol;
 
               g_scanner_get_next_token (scanner);
+              css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
+
+              /* Check for the next token being nth-child, parse in that
+               * case, and fallback into common state parsing if not.
+               */
+              if (g_scanner_peek_next_token (scanner) != G_TOKEN_SYMBOL)
+                return G_TOKEN_SYMBOL;
+
+              symbol = GPOINTER_TO_INT (scanner->next_value.v_symbol);
+
+              if (symbol == SYMBOL_FIRST_CHILD ||
+                  symbol == SYMBOL_LAST_CHILD ||
+                  symbol == SYMBOL_NTH_CHILD)
+                {
+                  GTokenType token;
 
-              if ((token = parse_pseudo_class (css_provider, scanner, path, &flags)) != G_TOKEN_NONE)
-                return token;
+                  if ((token = parse_nth_child (css_provider, scanner, &flags)) != G_TOKEN_NONE)
+                    return token;
+
+                  css_provider_pop_scope (css_provider);
+                }
+              else
+                {
+                  css_provider_pop_scope (css_provider);
+                  selector_path_prepend_region (path, region_name, 0);
+                  g_free (region_name);
+                  break;
+                }
             }
 
           selector_path_prepend_region (path, region_name, flags);
@@ -1054,10 +1107,6 @@ parse_selector (GtkCssProvider  *css_provider,
 
       g_scanner_get_next_token (scanner);
 
-      /* State is the last element in the selector */
-      if (path->state != GTK_STATE_NORMAL)
-        break;
-
       if (scanner->token == '>')
         {
           selector_path_prepend_combinator (path, COMBINATOR_CHILD);
@@ -1065,35 +1114,25 @@ parse_selector (GtkCssProvider  *css_provider,
         }
     }
 
-  if (scanner->token == ':' &&
-      path->state == GTK_STATE_NORMAL)
+  if (scanner->token == ':')
     {
-      GtkRegionFlags flags = 0;
-      GTokenType token;
-
       /* Add glob selector if path is empty */
       if (selector_path_depth (path) == 0)
         selector_path_prepend_glob (path);
 
-      if ((token = parse_pseudo_class (css_provider, scanner, path, &flags)) != G_TOKEN_NONE)
-        return token;
+      css_provider_push_scope (css_provider, SCOPE_PSEUDO_CLASS);
 
-      if (flags != 0)
+      while (scanner->token == ':')
         {
-          /* This means either a standalone :nth-child
-           * selector, or on a invalid element type.
-           */
-          return G_TOKEN_SYMBOL;
+          GTokenType token;
+
+          if ((token = parse_pseudo_class (css_provider, scanner, path)) != G_TOKEN_NONE)
+            return token;
+
+          g_scanner_get_next_token (scanner);
         }
 
-      g_scanner_get_next_token (scanner);
-    }
-  else if (scanner->token == G_TOKEN_SYMBOL)
-    {
-      /* A new pseudo-class was starting, but the state was already
-       * parsed, so nothing is supposed to go after that.
-       */
-      return G_TOKEN_LEFT_CURLY;
+      css_provider_pop_scope (css_provider);
     }
 
   return G_TOKEN_NONE;
@@ -1652,20 +1691,14 @@ gtk_css_provider_get_default (void)
         "@tooltip_bg_color: #eee1b3; \n"
         "@tooltip_fg_color: #000; \n"
         "\n"
-        "*, GtkTreeView > GtkButton {\n"
+        "*,\n"
+        "GtkTreeView > GtkButton {\n"
         "  background-color: @bg_color;\n"
         "  foreground-color: @fg_color;\n"
         "  text-color: @text_color; \n"
         "  base-color: @base_color; \n"
         "}\n"
         "\n"
-        "*:active {\n"
-        "  background-color: #c4c2bd;\n"
-        "  foreground-color: #000000;\n"
-        "  text-color: #c4c2bd; \n"
-        "  base-color: #9c9a94; \n"
-        "}\n"
-        "\n"
         "*:prelight {\n"
         "  background-color: #eeebe7;\n"
         "  foreground-color: #000000;\n"
@@ -1701,6 +1734,13 @@ gtk_css_provider_get_default (void)
         "GtkToggleButton:prelight {\n"
         "  text-color: #000; \n"
         "}\n"
+        "\n"
+        ".button:active {\n"
+        "  background-color: #c4c2bd;\n"
+        "  foreground-color: #000000;\n"
+        "  text-color: #c4c2bd; \n"
+        "  base-color: #9c9a94; \n"
+        "}\n"
         "\n";
 
       provider = gtk_css_provider_new ();
index 41b607f34f9ab0fdae39ce121aaa16a40087596c..cd3b2c0276e3a3839e7c44518129ea1ba83cb5a2 100644 (file)
@@ -343,7 +343,7 @@ rebuild_properties (GtkStyleContext *context)
         }
     }
 
-  gtk_style_set_get (priv->store, GTK_STATE_NORMAL,
+  gtk_style_set_get (priv->store, 0,
                      "engine", &priv->theming_engine,
                      NULL);
 }
@@ -488,14 +488,13 @@ gtk_style_context_remove_provider (GtkStyleContext  *context,
 void
 gtk_style_context_get_property (GtkStyleContext *context,
                                 const gchar     *property,
-                                GtkStateType     state,
+                                GtkStateFlags    state,
                                 GValue          *value)
 {
   GtkStyleContextPrivate *priv;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
   g_return_if_fail (value != NULL);
 
   priv = context->priv;
@@ -504,13 +503,12 @@ gtk_style_context_get_property (GtkStyleContext *context,
 
 void
 gtk_style_context_get_valist (GtkStyleContext *context,
-                              GtkStateType     state,
+                              GtkStateFlags    state,
                               va_list          args)
 {
   GtkStyleContextPrivate *priv;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = context->priv;
   gtk_style_set_get_valist (priv->store, state, args);
@@ -518,14 +516,13 @@ gtk_style_context_get_valist (GtkStyleContext *context,
 
 void
 gtk_style_context_get (GtkStyleContext *context,
-                       GtkStateType     state,
+                       GtkStateFlags    state,
                        ...)
 {
   GtkStyleContextPrivate *priv;
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = context->priv;
 
index bf0d87261a7697de81e6c32d6b0402f628bce76a..833ca71bee73ba5c12325085414ca45b7ef1372e 100644 (file)
@@ -61,13 +61,13 @@ void gtk_style_context_restore (GtkStyleContext *context);
 
 void gtk_style_context_get_property (GtkStyleContext *context,
                                      const gchar     *property,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      GValue          *value);
 void gtk_style_context_get_valist   (GtkStyleContext *context,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      va_list          args);
 void gtk_style_context_get          (GtkStyleContext *context,
-                                     GtkStateType     state,
+                                     GtkStateFlags    state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
 void          gtk_style_context_set_state    (GtkStyleContext *context,
index e8b96cc1cc216510cd37e882651160107e1f92c6..7c42f1f7d0121e8b785e4116412e84c429fe11df 100644 (file)
@@ -33,6 +33,7 @@
 typedef struct GtkStyleSetPrivate GtkStyleSetPrivate;
 typedef struct PropertyData PropertyData;
 typedef struct PropertyNode PropertyNode;
+typedef struct ValueData ValueData;
 
 struct PropertyNode
 {
@@ -42,10 +43,15 @@ struct PropertyNode
   GtkStylePropertyParser parse_func;
 };
 
+struct ValueData
+{
+  GtkStateFlags state;
+  GValue value;
+};
+
 struct PropertyData
 {
-  GValue default_value;
-  GValue values[GTK_STATE_LAST];
+  GArray *values;
 };
 
 struct GtkStyleSetPrivate
@@ -97,6 +103,7 @@ property_data_new (void)
   PropertyData *data;
 
   data = g_slice_new0 (PropertyData);
+  data->values = g_array_new (FALSE, FALSE, sizeof (ValueData));
 
   return data;
 }
@@ -104,17 +111,138 @@ property_data_new (void)
 static void
 property_data_free (PropertyData *data)
 {
-  gint i;
+  guint i;
 
-  for (i = 0; i <= GTK_STATE_INSENSITIVE; i++)
+  for (i = 0; i < data->values->len; i++)
     {
-      if (G_IS_VALUE (&data->values[i]))
-        g_value_unset (&data->values[i]);
+      ValueData *value_data;
+
+      value_data = &g_array_index (data->values, ValueData, i);
+
+      if (G_IS_VALUE (&value_data->value))
+        g_value_unset (&value_data->value);
     }
 
   g_slice_free (PropertyData, data);
 }
 
+static gboolean
+property_data_find_position (PropertyData  *data,
+                             GtkStateFlags  state,
+                             guint         *pos)
+{
+  gint min, max, mid;
+  gboolean found = FALSE;
+  guint position;
+
+  if (pos)
+    *pos = 0;
+
+  if (data->values->len == 0)
+    return FALSE;
+
+  /* Find position for the given state, or the position where
+   * it would be if not found, the array is ordered by the
+   * state flags.
+   */
+  min = 0;
+  max = data->values->len - 1;
+
+  do
+    {
+      ValueData *value_data;
+
+      mid = (min + max) / 2;
+      value_data = &g_array_index (data->values, ValueData, mid);
+
+      if (value_data->state == state)
+        {
+          found = TRUE;
+          position = mid;
+        }
+      else if (value_data->state < state)
+          position = min = mid + 1;
+      else
+        {
+          max = mid - 1;
+          position = mid;
+        }
+    }
+  while (!found && min <= max);
+
+  if (pos)
+    *pos = position;
+
+  return found;
+}
+
+static GValue *
+property_data_get_value (PropertyData  *data,
+                         GtkStateFlags  state)
+{
+  ValueData *val_data;
+  guint pos;
+
+  if (!property_data_find_position (data, state, &pos))
+    {
+      ValueData new = { 0 };
+
+      //val_data = &g_array_index (data->values, ValueData, pos);
+      new.state = state;
+      g_array_insert_val (data->values, pos, new);
+    }
+
+  val_data = &g_array_index (data->values, ValueData, pos);
+
+  return &val_data->value;
+}
+
+static GValue *
+property_data_match_state (PropertyData  *data,
+                           GtkStateFlags  state)
+{
+  guint pos;
+  gint i;
+
+  if (property_data_find_position (data, state, &pos))
+    {
+      ValueData *val_data;
+
+      /* Exact match */
+      val_data = &g_array_index (data->values, ValueData, pos);
+      return &val_data->value;
+    }
+
+  if (pos >= data->values->len)
+    pos = data->values->len - 1;
+
+  /* No exact match, go downwards the list to find
+   * the closest match to the given state flags, as
+   * a side effect, there is an implicit precedence
+   * of higher flags over the smaller ones.
+   */
+  for (i = pos; i >= 0; i--)
+    {
+      ValueData *val_data;
+
+      val_data = &g_array_index (data->values, ValueData, i);
+
+       /* Check whether any of the requested
+        * flags are set, and no other flags are.
+        *
+        * Also, no flags acts as a wildcard, such
+        * value should be always in the first position
+        * in the array (if present) anyways.
+        */
+      if (val_data->state == 0 ||
+          ((val_data->state & state) != 0 &&
+           (val_data->state & ~state) == 0))
+        return &val_data->value;
+    }
+
+  return NULL;
+}
+
 static void
 gtk_style_set_init (GtkStyleSet *set)
 {
@@ -331,12 +459,11 @@ gtk_style_set_lookup_color (GtkStyleSet *set,
   return g_hash_table_lookup (priv->color_map, name);
 }
 
-static void
-set_property_internal (GtkStyleSet  *set,
-                       const gchar  *property,
-                       gboolean      is_default,
-                       GtkStateType  state,
-                       const GValue *value)
+void
+gtk_style_set_set_property (GtkStyleSet   *set,
+                            const gchar   *property,
+                            GtkStateFlags  state,
+                            const GValue  *value)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
@@ -344,6 +471,10 @@ set_property_internal (GtkStyleSet  *set,
   GType value_type;
   GValue *val;
 
+  g_return_if_fail (GTK_IS_STYLE_SET (set));
+  g_return_if_fail (property != NULL);
+  g_return_if_fail (value != NULL);
+
   value_type = G_VALUE_TYPE (value);
   node = property_node_lookup (g_quark_try_string (property));
 
@@ -359,7 +490,7 @@ set_property_internal (GtkStyleSet  *set,
       g_return_if_fail (value_type == GDK_TYPE_COLOR || value_type == GTK_TYPE_SYMBOLIC_COLOR);
     }
   else
-    g_return_if_fail (node->property_type == G_VALUE_TYPE (value));
+    g_return_if_fail (node->property_type == value_type);
 
   priv = set->priv;
   prop = g_hash_table_lookup (priv->properties,
@@ -373,10 +504,7 @@ set_property_internal (GtkStyleSet  *set,
                            prop);
     }
 
-  if (is_default)
-    val = &prop->default_value;
-  else
-    val = &prop->values[state];
+  val = property_data_get_value (prop, state);
 
   if (G_VALUE_TYPE (val) == value_type)
     g_value_reset (val);
@@ -392,41 +520,14 @@ set_property_internal (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_set_default (GtkStyleSet  *set,
-                           const gchar  *property,
-                           const GValue *value)
-{
-  g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (property != NULL);
-  g_return_if_fail (value != NULL);
-
-  set_property_internal (set, property, TRUE, GTK_STATE_NORMAL, value);
-}
-
-void
-gtk_style_set_set_property (GtkStyleSet  *set,
-                            const gchar  *property,
-                            GtkStateType  state,
-                            const GValue *value)
-{
-  g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
-  g_return_if_fail (value != NULL);
-
-  set_property_internal (set, property, FALSE, state, value);
-}
-
-void
-gtk_style_set_set_valist (GtkStyleSet  *set,
-                          GtkStateType  state,
-                          va_list       args)
+gtk_style_set_set_valist (GtkStyleSet   *set,
+                          GtkStateFlags  state,
+                          va_list        args)
 {
   GtkStyleSetPrivate *priv;
   const gchar *property_name;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = set->priv;
   property_name = va_arg (args, const gchar *);
@@ -436,6 +537,7 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
       PropertyNode *node;
       PropertyData *prop;
       gchar *error = NULL;
+      GValue *val;
 
       node = property_node_lookup (g_quark_try_string (property_name));
 
@@ -456,14 +558,19 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
                                prop);
         }
 
-      g_value_init (&prop->values[state], node->property_type);
-      G_VALUE_COLLECT (&prop->values[state], args, 0, &error);
+      val = property_data_get_value (prop, state);
+
+      if (G_IS_VALUE (val))
+        g_value_unset (val);
+
+      g_value_init (val, node->property_type);
+      G_VALUE_COLLECT (val, args, 0, &error);
 
       if (error)
         {
           g_warning ("Could not set style property \"%s\": %s", property_name, error);
-          g_value_unset (&prop->values[state]);
-         g_free (error);
+          g_value_unset (val);
+          g_free (error);
           break;
         }
 
@@ -472,14 +579,13 @@ gtk_style_set_set_valist (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_set (GtkStyleSet  *set,
-                   GtkStateType  state,
+gtk_style_set_set (GtkStyleSet   *set,
+                   GtkStateFlags  state,
                    ...)
 {
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   va_start (args, state);
   gtk_style_set_set_valist (set, state, args);
@@ -505,10 +611,10 @@ resolve_color (GtkStyleSet *set,
 }
 
 gboolean
-gtk_style_set_get_property (GtkStyleSet  *set,
-                            const gchar  *property,
-                            GtkStateType  state,
-                            GValue       *value)
+gtk_style_set_get_property (GtkStyleSet   *set,
+                            const gchar   *property,
+                            GtkStateFlags  state,
+                            GValue        *value)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
@@ -517,7 +623,6 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 
   g_return_val_if_fail (GTK_IS_STYLE_SET (set), FALSE);
   g_return_val_if_fail (property != NULL, FALSE);
-  g_return_val_if_fail (state < GTK_STATE_LAST, FALSE);
   g_return_val_if_fail (value != NULL, FALSE);
 
   node = property_node_lookup (g_quark_try_string (property));
@@ -537,11 +642,9 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 
   g_value_init (value, node->property_type);
 
-  if (G_IS_VALUE (&prop->values[state]))
-    val = &prop->values[state];
-  else if (G_IS_VALUE (&prop->default_value))
-    val = &prop->default_value;
-  else
+  val = property_data_match_state (prop, state);
+
+  if (!val && G_IS_VALUE (&node->default_value))
     val = &node->default_value;
 
   g_return_val_if_fail (G_IS_VALUE (val), FALSE);
@@ -560,15 +663,14 @@ gtk_style_set_get_property (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_get_valist (GtkStyleSet  *set,
-                          GtkStateType  state,
-                          va_list       args)
+gtk_style_set_get_valist (GtkStyleSet   *set,
+                          GtkStateFlags  state,
+                          va_list        args)
 {
   GtkStyleSetPrivate *priv;
   const gchar *property_name;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = set->priv;
   property_name = va_arg (args, const gchar *);
@@ -604,14 +706,9 @@ gtk_style_set_get_valist (GtkStyleSet  *set,
           GValue *val = NULL;
 
           if (prop)
-            {
-              if (G_IS_VALUE (&prop->values[state]))
-                val = &prop->values[state];
-              else if (G_IS_VALUE (&prop->default_value))
-                val = &prop->default_value;
-            }
+            val = property_data_match_state (prop, state);
 
-          if (!val)
+          if (!val && G_IS_VALUE (&node->default_value))
             val = &node->default_value;
 
           if (G_VALUE_TYPE (val) == GTK_TYPE_SYMBOLIC_COLOR)
@@ -637,14 +734,13 @@ gtk_style_set_get_valist (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_get (GtkStyleSet  *set,
-                   GtkStateType  state,
+gtk_style_set_get (GtkStyleSet   *set,
+                   GtkStateFlags  state,
                    ...)
 {
   va_list args;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   va_start (args, state);
   gtk_style_set_get_valist (set, state, args);
@@ -652,17 +748,17 @@ gtk_style_set_get (GtkStyleSet  *set,
 }
 
 void
-gtk_style_set_unset_property (GtkStyleSet  *set,
-                              const gchar  *property,
-                              GtkStateType  state)
+gtk_style_set_unset_property (GtkStyleSet   *set,
+                              const gchar   *property,
+                              GtkStateFlags  state)
 {
   GtkStyleSetPrivate *priv;
   PropertyNode *node;
   PropertyData *prop;
+  guint pos;
 
   g_return_if_fail (GTK_IS_STYLE_SET (set));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   node = property_node_lookup (g_quark_try_string (property));
 
@@ -679,7 +775,17 @@ gtk_style_set_unset_property (GtkStyleSet  *set,
   if (!prop)
     return;
 
-  g_value_unset (&prop->values[state]);
+  if (property_data_find_position (prop, state, &pos))
+    {
+      ValueData *data;
+
+      data = &g_array_index (prop->values, ValueData, pos);
+
+      if (G_IS_VALUE (&data->value))
+        g_value_unset (&data->value);
+
+      g_array_remove_index (prop->values, pos);
+    }
 }
 
 void
@@ -735,62 +841,38 @@ gtk_style_set_merge (GtkStyleSet       *set,
   while (g_hash_table_iter_next (&iter, &key, &value))
     {
       PropertyData *prop_to_merge = value;
-      PropertyData *prop = NULL;
-      GtkStateType i;
+      PropertyData *prop;
+      guint i;
 
-      for (i = GTK_STATE_NORMAL; i < GTK_STATE_LAST; i++)
+      prop = g_hash_table_lookup (priv->properties, key);
+
+      if (!prop)
         {
-          if (G_VALUE_TYPE (&prop_to_merge->values[i]) == G_TYPE_INVALID)
-            continue;
+          prop = property_data_new ();
+          g_hash_table_insert (priv->properties, key, prop);
+        }
 
-          if (!prop)
-            prop = g_hash_table_lookup (priv->properties, key);
+      for (i = 0; i < prop_to_merge->values->len; i++)
+        {
+          ValueData *data;
+          GValue *value;
 
-          if (!prop)
-            {
-              prop = property_data_new ();
-              g_hash_table_insert (priv->properties, key, prop);
-            }
+          data = &g_array_index (prop_to_merge->values, ValueData, i);
+          value = property_data_get_value (prop, data->state);
 
-          if (replace ||
-              G_VALUE_TYPE (&prop->values[i]) == G_TYPE_INVALID)
+          if (replace || !G_IS_VALUE (value))
             {
-              if (!G_IS_VALUE (&prop->values[i]))
-                g_value_init (&prop->values[i], G_VALUE_TYPE (&prop_to_merge->values[i]));
-              else if (G_VALUE_TYPE (&prop->values[i]) != G_VALUE_TYPE (&prop_to_merge->values[i]))
+              if (!G_IS_VALUE (value))
+                g_value_init (value, G_VALUE_TYPE (&data->value));
+              else if (G_VALUE_TYPE (value) != G_VALUE_TYPE (&data->value))
                 {
-                  g_value_unset (&prop->values[i]);
-                  g_value_init (&prop->values[i], G_VALUE_TYPE (&prop_to_merge->values[i]));
+                  g_value_unset (value);
+                  g_value_init (value, G_VALUE_TYPE (&data->value));
                 }
 
-              g_value_copy (&prop_to_merge->values[i],
-                            &prop->values[i]);
+              g_value_copy (&data->value, value);
             }
         }
-
-      if (G_IS_VALUE (&prop_to_merge->default_value) &&
-          (replace || !prop || !G_IS_VALUE (&prop->default_value)))
-        {
-          if (!prop)
-            prop = g_hash_table_lookup (priv->properties, key);
-
-          if (!prop)
-            {
-              prop = property_data_new ();
-              g_hash_table_insert (priv->properties, key, prop);
-            }
-
-          if (!G_IS_VALUE (&prop->default_value))
-            g_value_init (&prop->default_value, G_VALUE_TYPE (&prop_to_merge->default_value));
-          else if (G_VALUE_TYPE (&prop->default_value) != G_VALUE_TYPE (&prop_to_merge->default_value))
-            {
-              g_value_unset (&prop->default_value);
-              g_value_init (&prop->default_value, G_VALUE_TYPE (&prop_to_merge->default_value));
-            }
-
-          g_value_copy (&prop_to_merge->default_value,
-                        &prop->default_value);
-        }
     }
 }
 
index cf46a2fab5ad73b3d4652ab93986192bec52e18d..8b8750c588530feb25097fcec9f24b290b59d28f 100644 (file)
@@ -71,34 +71,31 @@ void               gtk_style_set_map_color    (GtkStyleSet      *set,
 GtkSymbolicColor * gtk_style_set_lookup_color (GtkStyleSet *set,
                                                const gchar *name);
 
-void     gtk_style_set_set_default  (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     const GValue *value);
-void     gtk_style_set_set_property (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     GtkStateType  state,
-                                     const GValue *value);
-void     gtk_style_set_set_valist   (GtkStyleSet  *set,
-                                     GtkStateType  state,
-                                     va_list       args);
-void     gtk_style_set_set          (GtkStyleSet  *set,
-                                     GtkStateType  state,
+void     gtk_style_set_set_property (GtkStyleSet   *set,
+                                     const gchar   *property,
+                                     GtkStateFlags  state,
+                                     const GValue  *value);
+void     gtk_style_set_set_valist   (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
+                                     va_list        args);
+void     gtk_style_set_set          (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
-gboolean gtk_style_set_get_property (GtkStyleSet  *set,
-                                     const gchar  *property,
-                                     GtkStateType  state,
-                                     GValue       *value);
-void     gtk_style_set_get_valist   (GtkStyleSet  *set,
-                                     GtkStateType  state,
-                                     va_list       args);
-void     gtk_style_set_get          (GtkStyleSet  *set,
-                                     GtkStateType  state,
+gboolean gtk_style_set_get_property (GtkStyleSet   *set,
+                                     const gchar   *property,
+                                     GtkStateFlags  state,
+                                     GValue        *value);
+void     gtk_style_set_get_valist   (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
+                                     va_list        args);
+void     gtk_style_set_get          (GtkStyleSet   *set,
+                                     GtkStateFlags  state,
                                      ...) G_GNUC_NULL_TERMINATED;
 
-void     gtk_style_set_unset_property (GtkStyleSet  *set,
-                                       const gchar  *property,
-                                       GtkStateType  state);
+void     gtk_style_set_unset_property (GtkStyleSet   *set,
+                                       const gchar   *property,
+                                       GtkStateFlags  state);
 
 void     gtk_style_set_clear          (GtkStyleSet  *set);
 
index f90946be8480763b98921d2a8618e30fcb6d1ba7..a7a740b612f740367b085dd910d788ad2950ab58 100644 (file)
@@ -216,14 +216,13 @@ gtk_theming_engine_register_property (GtkThemingEngine       *engine,
 void
 gtk_theming_engine_get_property (GtkThemingEngine *engine,
                                  const gchar      *property,
-                                 GtkStateType      state,
+                                 GtkStateFlags     state,
                                  GValue           *value)
 {
   GtkThemingEnginePrivate *priv;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
   g_return_if_fail (property != NULL);
-  g_return_if_fail (state < GTK_STATE_LAST);
   g_return_if_fail (value != NULL);
 
   priv = engine->priv;
@@ -232,13 +231,12 @@ gtk_theming_engine_get_property (GtkThemingEngine *engine,
 
 void
 gtk_theming_engine_get_valist (GtkThemingEngine *engine,
-                               GtkStateType      state,
+                               GtkStateFlags     state,
                                va_list           args)
 {
   GtkThemingEnginePrivate *priv;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = engine->priv;
   gtk_style_context_get_valist (priv->context, state, args);
@@ -246,14 +244,13 @@ gtk_theming_engine_get_valist (GtkThemingEngine *engine,
 
 void
 gtk_theming_engine_get (GtkThemingEngine *engine,
-                        GtkStateType      state,
+                        GtkStateFlags     state,
                         ...)
 {
   GtkThemingEnginePrivate *priv;
   va_list args;
 
   g_return_if_fail (GTK_IS_THEMING_ENGINE (engine));
-  g_return_if_fail (state < GTK_STATE_LAST);
 
   priv = engine->priv;
 
@@ -509,19 +506,13 @@ gtk_theming_engine_render_check (GtkThemingEngine *engine,
   GdkColor *fg_color, *base_color, *text_color;
   const GtkWidgetPath *path;
   GtkStateFlags flags;
-  GtkStateType state;
   gint exterior_size, interior_size, thickness, pad;
 
   flags = gtk_theming_engine_get_state (engine);
   path = gtk_theming_engine_get_path (engine);
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "base-color", &base_color,
                           "text-color", &text_color,
@@ -625,7 +616,6 @@ gtk_theming_engine_render_option (GtkThemingEngine *engine,
   GtkStateFlags flags;
   GdkColor *base_color, *fg_color, *text_color;
   const GtkWidgetPath *path;
-  GtkStateType state;
   gint exterior_size, interior_size, pad, thickness;
   gdouble radius;
 
@@ -637,12 +627,7 @@ gtk_theming_engine_render_option (GtkThemingEngine *engine,
 
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "base-color", &base_color,
                           "text-color", &text_color,
@@ -758,21 +743,13 @@ gtk_theming_engine_render_arrow (GtkThemingEngine *engine,
                                  gdouble           size)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *fg_color;
 
   cairo_save (cr);
 
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           NULL);
 
@@ -900,29 +877,17 @@ gtk_theming_engine_render_background (GtkThemingEngine *engine,
                                       gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *color;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_SELECTED)
-    state = GTK_STATE_SELECTED;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   if (gtk_theming_engine_has_class (engine, "entry"))
-    gtk_theming_engine_get (engine, state,
+    gtk_theming_engine_get (engine, flags,
                             "base-color", &color,
                             NULL);
   else
-    gtk_theming_engine_get (engine, state,
+    gtk_theming_engine_get (engine, flags,
                             "background-color", &color,
                             NULL);
 
@@ -958,23 +923,15 @@ gtk_theming_engine_render_frame (GtkThemingEngine *engine,
                                  gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor lighter, darker;
   GdkColor *bg_color;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1125,7 +1082,6 @@ gtk_theming_engine_render_expander (GtkThemingEngine *engine,
 {
   GtkStateFlags flags;
   GdkColor *bg_color, *fg_color, *base_color;
-  GtkStateType state;
   double vertical_overshoot;
   int diameter;
   double radius;
@@ -1139,14 +1095,7 @@ gtk_theming_engine_render_expander (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           "background-color", &bg_color,
                           "base-color", &base_color,
@@ -1241,7 +1190,6 @@ gtk_theming_engine_render_focus (GtkThemingEngine *engine,
                                  gdouble           height)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *color;
   gint line_width;
   gint8 *dash_list;
@@ -1249,14 +1197,7 @@ gtk_theming_engine_render_focus (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &color,
                           NULL);
 
@@ -1320,7 +1261,6 @@ gtk_theming_engine_render_line (GtkThemingEngine *engine,
 {
   GdkColor *bg_color, darker, lighter;
   GtkStateFlags flags;
-  GtkStateType state;
   gint i, thickness, thickness_dark, thickness_light, len;
   cairo_matrix_t matrix;
   gdouble angle;
@@ -1333,14 +1273,7 @@ gtk_theming_engine_render_line (GtkThemingEngine *engine,
   flags = gtk_theming_engine_get_state (engine);
   cairo_save (cr);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1535,7 +1468,6 @@ gtk_theming_engine_render_layout (GtkThemingEngine *engine,
 {
   GdkColor *fg_color;
   GtkStateFlags flags;
-  GtkStateType state;
   GdkScreen *screen;
 
   cairo_save (cr);
@@ -1543,24 +1475,13 @@ gtk_theming_engine_render_layout (GtkThemingEngine *engine,
 
   /* FIXME: Set clipping */
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_SELECTED)
-    state = GTK_STATE_SELECTED;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "foreground-color", &fg_color,
                           NULL);
 
   screen = gtk_theming_engine_get_screen (engine);
 
-  if (state == GTK_STATE_INSENSITIVE)
+  if (gtk_theming_engine_is_state_set (engine, GTK_STATE_INSENSITIVE))
     {
       PangoLayout *insensitive_layout;
 
@@ -1629,7 +1550,6 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
                                      gdouble           xy1_gap)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
   guint sides;
@@ -1637,16 +1557,9 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1786,25 +1699,15 @@ gtk_theming_engine_render_extension (GtkThemingEngine *engine,
                                      GtkPositionType   gap_side)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
 
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
@@ -1956,7 +1859,6 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine,
                                   GtkOrientation    orientation)
 {
   GtkStateFlags flags;
-  GtkStateType state;
   GdkColor *bg_color;
   GdkColor lighter, darker;
   gint xx, yy;
@@ -1964,18 +1866,9 @@ gtk_theming_engine_render_handle (GtkThemingEngine *engine,
   cairo_save (cr);
   flags = gtk_theming_engine_get_state (engine);
 
-  if (flags & GTK_STATE_FLAG_ACTIVE)
-    state = GTK_STATE_ACTIVE;
-  else if (flags & GTK_STATE_FLAG_PRELIGHT)
-    state = GTK_STATE_PRELIGHT;
-  else if (flags & GTK_STATE_FLAG_INSENSITIVE)
-    state = GTK_STATE_INSENSITIVE;
-  else
-    state = GTK_STATE_NORMAL;
-
   cairo_set_line_width (cr, 1);
 
-  gtk_theming_engine_get (engine, state,
+  gtk_theming_engine_get (engine, flags,
                           "background-color", &bg_color,
                           NULL);
   color_shade (bg_color, 0.7, &darker);
index 96962067e2810a6238c2d1ac17e9f639884e3bef..326fc63db4a2888d66c4053811cbad44606f8831 100644 (file)
@@ -147,13 +147,13 @@ void gtk_theming_engine_register_property (GtkThemingEngine       *engine,
 
 void gtk_theming_engine_get_property (GtkThemingEngine *engine,
                                       const gchar      *property,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       GValue           *value);
 void gtk_theming_engine_get_valist   (GtkThemingEngine *engine,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       va_list           args);
 void gtk_theming_engine_get          (GtkThemingEngine *engine,
-                                      GtkStateType      state,
+                                      GtkStateFlags     state,
                                       ...) G_GNUC_NULL_TERMINATED;
 
 void gtk_theming_engine_get_style_property (GtkThemingEngine *engine,